package gui.other;

import enums.OperandsEnum;
import j_util.Utiles;
import model.TruthTable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Dialogo que permite realizar la union de dos tablas de verdad. Permite buscar un archivo de tabla de verdad,
 * y elegir  un operador de tabla de verdad con el cual se produce la union de las tablas.
 * Permite establecer si la tabla proveniente del archivo elegido aparecera delante o detras del operador elegido.
 * Se asume que la tabla faltante se provee de alguna forma;
 *
 * @author Jose Martin Rozanec;
 */
public class TruthTableOperatorsDialog extends JDialog {
    private javax.swing.JButton acceptButton;
    private javax.swing.JButton cancelButton;
    private javax.swing.JButton bicondicionalButton;
    private javax.swing.JButton condicionalButton;
    private javax.swing.JButton conjuncionButton;
    private javax.swing.JButton disyuncionExcButton;
    private javax.swing.JButton disyuncionIncButton;
    private javax.swing.JButton incompatibilidadButton;
    private javax.swing.JButton negacionButton;
    private javax.swing.JButton negacionConjuntaButton;
    private javax.swing.JPanel operadoresPanel;
    private javax.swing.JPanel filechooserPanel;
    private JCheckBox beforeCheckBox;

    private JFileChooser fileChooser;
    private boolean accepted;
    private OperandsEnum operand;
    private boolean beforeOperator;
    private String filePath;

    /**
     * Constructor;
     *
     * @param fileChooser;
     */
    public TruthTableOperatorsDialog(JFileChooser fileChooser) {
        this.fileChooser = fileChooser;
        initComponents();
        layoutComponents();
    }

    /**
     * Inicializa los elementos del dialogo y los dispone visualmente;
     */
    private void initComponents() {
        setIconImage(Utiles.createImageIcon("/gui/images/other/logicaIcon.png").getImage());
        filechooserPanel = new javax.swing.JPanel();
        operadoresPanel = new javax.swing.JPanel();
        negacionButton = new javax.swing.JButton();
        conjuncionButton = new javax.swing.JButton();
        disyuncionIncButton = new javax.swing.JButton();
        disyuncionExcButton = new javax.swing.JButton();
        condicionalButton = new javax.swing.JButton();
        bicondicionalButton = new javax.swing.JButton();
        negacionConjuntaButton = new javax.swing.JButton();
        incompatibilidadButton = new javax.swing.JButton();
        acceptButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        beforeCheckBox = new JCheckBox("Agregar la tabla abierta antes del operador seleccionado");
        operand = null;
        filePath = null;

        negacionButton.setText("Negacion");
        negacionButton.setMnemonic('q');
        negacionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.NEGACION;
            }
        });

        conjuncionButton.setText("Conjuncion");
        conjuncionButton.setMnemonic('a');
        conjuncionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.CONJUNCION;
            }
        });

        disyuncionIncButton.setText("Disyuncion inclusiva");
        disyuncionIncButton.setMnemonic('w');
        disyuncionIncButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.DISYUNCION_INCLUSIVA;
            }
        });

        disyuncionExcButton.setText("Disyuncion exclusiva");
        disyuncionExcButton.setMnemonic('s');
        disyuncionExcButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.DISYUNCION_EXCLUSIVA;
            }
        });

        condicionalButton.setText("Condicional");
        condicionalButton.setMnemonic('e');
        condicionalButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.CONDICIONAL;
            }
        });

        bicondicionalButton.setText("Bicondicional");
        bicondicionalButton.setMnemonic('d');
        bicondicionalButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.BICONDICIONAL;
            }
        });

        negacionConjuntaButton.setText("Negacion conjunta");
        negacionConjuntaButton.setMnemonic('r');
        negacionConjuntaButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.NEGACION_CONJUNTA;
            }
        });

        incompatibilidadButton.setText("Incompatibilidad");
        incompatibilidadButton.setMnemonic('f');
        incompatibilidadButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                operand = OperandsEnum.INCOMPATIBILIDAD;
            }
        });

        acceptButton.setText("Aceptar");
        acceptButton.setMnemonic(KeyEvent.VK_ENTER);
        acceptButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (operand == null) {
                    JOptionPane.showMessageDialog(TruthTableOperatorsDialog.this, "Por favor, seleccione un operador que una las tablas!");
                } else {
                    if (filePath == null) {
                        JOptionPane.showMessageDialog(TruthTableOperatorsDialog.this, "Por favor, abra un archivo que corresponda a una tabla de verdad!");
                    } else {
                        try {
                            RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw");
                            if (!randomAccessFile.readUTF().startsWith(TruthTable.openTag())) {
                                JOptionPane.showMessageDialog(TruthTableOperatorsDialog.this, "Por favor, abra un archivo que corresponda a una tabla de verdad!");
                            } else {
                                accepted = true;
                                beforeOperator = beforeCheckBox.isSelected();
                                dispose();
                            }
                        } catch (FileNotFoundException e1) {
                            JOptionPane.showMessageDialog(TruthTableOperatorsDialog.this, "Se ha producido un error al leer el archivo!", "", JOptionPane.WARNING_MESSAGE);
                        } catch (IOException e1) {
                            JOptionPane.showMessageDialog(TruthTableOperatorsDialog.this, "Se ha producido un error al leer el archivo!", "", JOptionPane.WARNING_MESSAGE);
                        }
                    }
                }
            }
        });

        cancelButton.setText("Cancelar");
        cancelButton.setMnemonic(KeyEvent.VK_ESCAPE);
        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                accepted = false;
                dispose();
            }
        });

        Dimension buttonsDimension = new Dimension(155, 25);
        negacionButton.setPreferredSize(buttonsDimension);
        conjuncionButton.setPreferredSize(buttonsDimension);
        disyuncionExcButton.setPreferredSize(buttonsDimension);
        disyuncionIncButton.setPreferredSize(buttonsDimension);
        condicionalButton.setPreferredSize(buttonsDimension);
        bicondicionalButton.setPreferredSize(buttonsDimension);
        negacionConjuntaButton.setPreferredSize(buttonsDimension);
        incompatibilidadButton.setPreferredSize(buttonsDimension);
        acceptButton.setPreferredSize(buttonsDimension);
        cancelButton.setPreferredSize(buttonsDimension);

        negacionButton.setEnabled(false);
    }

    /**
     * Dispone los elementos visuales del dialogo;
     */
    private void layoutComponents() {
        filechooserPanel.setPreferredSize(new Dimension(250, 450));
        fileChooser.setControlButtonsAreShown(false);
//        filechooserPanel.add(new JLabel(Utiles.createImageIcon("/gui/images/filechooserPanel.png")));
        add(fileChooser, BorderLayout.CENTER);
        operadoresPanel.setLayout(new GridBagLayout());
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        int gridx = 0;
        int gridy = 0;
        gridBagConstraints.gridy = gridy;
        gridBagConstraints.gridx = gridx;
        //todo START FILECHOOSER PANEL
        gridBagConstraints.gridwidth = 4;
        operadoresPanel.add(new JLabel(Utiles.createImageIcon("/gui/images/truth_table/separator.png")), gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridwidth = 1;
        //todo END OF FILECHOOSER PANEL
        gridBagConstraints.gridheight = 1;
        gridBagConstraints.gridwidth = 1;
        operadoresPanel.add(negacionButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(disyuncionIncButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(condicionalButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(negacionConjuntaButton, gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        operadoresPanel.add(conjuncionButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(disyuncionExcButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(bicondicionalButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(incompatibilidadButton, gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        gridBagConstraints.gridwidth = 4;
        operadoresPanel.add(new JLabel(Utiles.createImageIcon("/gui/images/truth_table/separator.png")), gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        gridBagConstraints.gridwidth = 3;
        operadoresPanel.add(beforeCheckBox, gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        gridBagConstraints.gridwidth = 4;
        operadoresPanel.add(new JLabel(Utiles.createImageIcon("/gui/images/truth_table/separator.png")), gridBagConstraints);
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = ++gridx;
        gridBagConstraints.gridx = ++gridx;
        gridBagConstraints.gridwidth = 1;
        operadoresPanel.add(acceptButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(cancelButton, gridBagConstraints);

        add(operadoresPanel, BorderLayout.PAGE_END);
    }

    /**
     * Permite conocer si se ha aceptado;
     *
     * @return boolean accepted;
     */
    public boolean isAccepted() {
        return accepted;
    }

    /**
     * Permite conocer si la tabla de verdad abierta se coloce delante del operador;
     *
     * @return boolean isBeforeOperator;
     */
    public boolean isBeforeOperator() {
        return beforeOperator;
    }

    /**
     * Permite obtener el operador elegido;
     *
     * @return OperandsEnum;
     */
    public OperandsEnum getOperator() {
        return operand;
    }

    /**
     * Permite obtener la tabla de verdad abierta;
     *
     * @return TruthTable - tabla de verdad abierta;
     */
    public TruthTable getTruthTable() {
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw");
            return TruthTable.fromXML(randomAccessFile.readUTF());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        TruthTableOperatorsDialog truthTableOperatorsDialog = new TruthTableOperatorsDialog(new JFileChooser());
        truthTableOperatorsDialog.setModal(true);
        truthTableOperatorsDialog.setPreferredSize(new Dimension(640, 490));
        truthTableOperatorsDialog.setMinimumSize(new Dimension(640, 490));
        truthTableOperatorsDialog.setVisible(true);
        System.exit(0);
    }
}
